package xpn.platform.modules.workflow.runtime.todo;

import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
import org.springframework.data.rest.core.config.Projection;
import xpn.platform.common.repository.XpnRepository;
import xpn.platform.modules.workflow.definition.state.State;
import xpn.platform.modules.workflow.runtime.instance.Instance;

@RepositoryRestResource(path = "workflow_runtime_todos", excerptProjection = TodoDefaultProjection.class)
public interface TodoDAO extends XpnRepository<Todo, Long> {

    /**
     * 根据执行者Id获取待办事项列表
     *
     * @param instance    流程实例
     * @param isCompleted 是否完成
     * @return 待办事项列表
     */
    Page<Todo> findByInstanceAndCompleted(Instance instance, boolean isCompleted, Pageable pageable);

    /**
     * 根据执行者Id获取待办事项列表
     *
     * @param id          执行者Id
     * @param isCompleted 是否完成
     * @return 待办事项列表
     */
    Page<Todo> findByExecutorIdAndCompleted(String id, boolean isCompleted, Pageable pageable);

    /**
     * 获取执行者在指定流程实例中的所有待办事项列表
     *
     * @param executorId  执行者Id
     * @param instance    流程实例
     * @param isCompleted true 代表获取完成的待办事项列表，false 相反
     * @return 待办事项列表
     */
    List<Todo> findByExecutorIdAndInstanceAndCompleted(String executorId, Instance instance, boolean isCompleted);

    /**
     * 获取执行者在指定流程实例中的所有待办事项列表
     *
     * @param instance    流程实例
     * @param isCompleted true 代表获取完成的待办事项列表，false 相反
     * @return 待办事项列表
     */
    List<Todo> findByInstanceAndCompleted(Instance instance, boolean isCompleted);

    /**
     * 根据流程实例获取待办事项列表
     *
     * @param instance 流程实例
     * @return 待办事项列表
     */
    List<Todo> findByInstance(Instance instance);

    /**
     * 根据流程实例获取待办事项列表
     *
     * @param instance 流程实例
     * @return 待办事项列表
     */
    @Query(value = "select e from Todo e where  e.instance.id in (:instanceIds) and e.state.id=:stateId and e.completed=false order by e.emergency desc,e.modifiedTime asc")
    List<Todo> findByInstanceIdsAndStateIdAndTodo(@Param(value = "instanceIds") List<Long> instanceIds, @Param(value = "stateId") Long stateId);

    /**
     * 根据流程实例和状态获取待办事项列表
     *
     * @param instance 流程实例
     * @param state    状态
     * @return 待办事项列表
     */
    List<Todo> findByInstanceAndState(Instance instance, State state);

    /**
     * 根据批次号查找
     *
     * @param batchNumber 批次号
     * @return 待办事项列表
     */
    List<Todo> findByBatchNumber(String batchNumber);

}

@Projection(name = "default", types = {Todo.class})
interface TodoDefaultProjection {
    Long getId();

    String getBatchNumber();

    boolean getCompleted();

    String getExecutorId();

    String getExecutorName();

    Integer getEmergency();

    Instance getInstance();

    State getState();

    String getStateName();

    Date getTimeLimit();
}

@Projection(name = "list", types = {Todo.class})
interface TodoListProjection {
    Long getId();

    String getBatchNumber();

    boolean getCompleted();

    String getExecutorId();

    String getExecutorName();

    Integer getEmergency();

    @Value("#{ target.instance != null ? target.instance.id : null}")
    Long getInstanceId();

    String getStateName();

    Date getDeadLine();

    Long getTimeLimit();
}
